/**
 *  字典树（前缀树）
 *  @param Array wordList 用于初始化的单词数组
 *  @metods 内置方法
 *      init(Array)： 传入单词数组，重新初始化字典树
 *      insert(String)： 传入单词字符串，插入当前字典树
 *      isPrefix(String)： 传入字符串，判断字典树中是否存在有单词前缀为该字符串
 *      getWordList(tree)： 传入一棵字典树，获取字典树中的所有单词，默认为本身
 *      getWordsByPrefix(String)： 传入字符串，获取字典树中所有以该字符串为前缀的单词
 *      delete(String)： 传入单词字符串，将该单词从字典树中删除，成功则返回true
 *  @returns {TrieTree}
 *  */ 

 class TrieTree {
    constructor(wordList = []) {
        this.init(wordList);
    }
    init(wordList){
        this.tree = {};
        for(const word of wordList){
            this.insert(word);
        }
    }
    insert(word){
        let tree = this.tree;
        for(const w of word){
            if(!tree[w]) tree[w] = {};
            tree = tree[w];
        }
        tree.isEnd = true;
    }
    isPrefix(prefix){
        let tree = this.tree;
        for(const w of prefix){
            if(!tree[w]) return false;
            tree = tree[w];
        }
        return true;
    }
    getWordList(tree = this.tree,prefix = ''){
        const wordList = [];
        for(const w in tree){
            if(w == 'isEnd') wordList.push(prefix);
            else if(tree[w]){
                wordList.push(...this.getWordList(tree[w],prefix + w));
            }
        }
        return wordList;
    }
    getWordsByPrefix(prefix = ''){
        let tree = this.tree;
        for(const w of prefix){
            if(!tree[w]) return false;
            tree = tree[w];
        }
        return this.getWordList(tree,prefix);
    }
    delete(word,tree = this.tree, i = 0){
        if(i == word.length){
            if(tree.isEnd){
                delete tree.isEnd;
                return true;
            }
            return false;
        }
        const flag = this.delete(word,tree[word[i]],i+1);
        if(flag){
            if(Object.keys(tree[word[i]]).length == 0) delete tree[word[i]];
        }
        return flag;
    }
}

exports.TrieTree = TrieTree;